package irc.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;

/**
 * This class contains the user-list of a specific channel.
 * @since 1.5
 * @version 3.1
 * @author ?
 *
 */
public class ListController{
	private BaseController CC;
	private JList<String> list;						// list of users.
	private DefaultListModel<String> defListMod;	// model to hold the list
	private JPopupMenu listPopup;					// pop-up for the list.
	private String nickInUse;				// the nick who is right-clicked on.
	private String myChannelName;			// the channel the nameList is in.
	
	
	/**
	 * @since 1.5
	 * @version 3.1
	 */
	public ListController(BaseController CC, String channel){
		defListMod = new DefaultListModel<String>();	
		listPopup = new JPopupMenu();					// popup for a name.
		nickInUse = new String("");						// target name who is in use.
		myChannelName = channel;						// this userList-s channel.
		this.CC = CC;									// Access to the BaseController.
		
		
		/* Goes through all the users in a given channel, and adding users to the list
			and adding "@" to operators name */
		for(String name : CC.getUsers(channel)){
			//put OP's at the top of the list..			
			if(CC.hasOp(channel, name)){
				name = "@"+name;
				defListMod.insertElementAt(name, 0);
			}	
			else			
				defListMod.addElement(name);
			
		}
		
		// create the list of users.
		
		list = new JList<String>(defListMod);
	
		list.setFixedCellWidth(100);
		
		listPopupMenu();		// create the popup for the user-list.
		listActionListener();	// add right- and double- click to the user-list.
	}

	
	/**
	 * Function. Add right-click and double-click action to the list.
	 * @since 2.0
	 * @version 2.9
	 */
	public void listActionListener(){
		list.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				
				// Double-click on a name:
				if(e.getClickCount() == 2){
					 int index = list.locationToIndex(e.getPoint());
					 ListModel dlm = list.getModel();
					 Object item = dlm.getElementAt(index);;
					 list.ensureIndexIsVisible(index);
					 
					
					 //check if user has OP (removes @ to get the right name for OP's)   
					 String name = item.toString();
					     if(name.startsWith("@")){
					    	 name = name.substring(1);
					     }
					 CC.createChatWindow(name);
				     }
				   
				// right-click on a name
				if (SwingUtilities.isRightMouseButton(e)) {
					final int index = list.locationToIndex(e.getPoint());
					list.setSelectedIndex(index);			// set focus on the name.
					ListModel dlm = list.getModel();
					Object item = dlm.getElementAt(index);;
					list.ensureIndexIsVisible(index);
					
					nickInUse = item.toString();
					listPopup.show (e.getComponent(), e.getX(), e.getY());   
				   }
			  }
			  
		});
		
	}
	
	
	/**
	 * Function. returns the user-list.
	 * @since 2.0
	 * @version 2.0
	 */
	public JList getList() {
		return list;
	}
	
	
	/**
	 * Adds nick of the person who joined to the list.
	 * @since 2.0
	 * @version 2.0
	 */
	public void add(String nick) {
		defListMod.addElement(nick);
	}


	/**
	 * Removes nick of the person who parted from the list.
	 * @since 2.0
	 * @version 2.0
	 */
	public void remove(String channel, String nick) {
		if(defListMod.contains("@"+nick)){
			String temp = "@"+nick;
			defListMod.removeElement(temp);			
		}
		else{		
		defListMod.removeElement(nick);
		}
	}
	
	/**
	 * Updates the list if a user changes nick
	 * @since 2.0
	 * @version 2.0
	 */
	public void update(String nick, String newNick, String channel) {
		if(CC.hasOp(channel, newNick)){
			nick = "@"+nick;
			newNick = "@"+newNick;

			}	
		
		if(defListMod.contains(nick)){
			int i =	defListMod.indexOf(nick);
		
			defListMod.insertElementAt(newNick, i);
			defListMod.removeElement(nick);
		}
	}
	
	/**
	 * Sorts the list, so that new OP's will be put on top of the list (kinda buggy)
	 * @since 2.0
	 * @version 2.0
	 */
	
	public void opSort (String channel){
		for(String name : CC.getUsers(channel)){
			String nameTmp = "@"+name;
			if(defListMod.contains(nameTmp)){			
			defListMod.removeElement("@"+name);
			defListMod.insertElementAt(nameTmp, 0);			
		}
		}
	}
	
		
	
	/**
	 * PopupMenu for the list of names in every channel.
	 * @since 2.1
	 * @version 2.3
	 */
	public void listPopupMenu(){
        JMenuItem listWhoIs = new JMenuItem("WhoIs");
        JMenuItem listChat = new JMenuItem("Chat");
        JMenu listControl = new JMenu("Control");
        JMenuItem listSlap = new JMenuItem("Slap!");
        
        listControlItem(listControl);
        listPopup.add(listWhoIs);
        listPopup.add(listChat);
        listPopup.add(new JSeparator());
        listPopup.add(listControl);
        listPopup.add(new JSeparator());
        listPopup.add(listSlap);
        
        PopupListActionListener(listWhoIs, listChat, listSlap);
	}
	
	
	/**
	 * JMenuItems for the JMenu: control.
	 * @since 2.1
	 * @version 2.3
	 */
	public void listControlItem(JMenu listControl){
	    JMenuItem controlOperator = new JMenuItem("OP");
        JMenuItem controlDeOperator = new JMenuItem("DEOP");
        JMenuItem controlKick = new JMenuItem("Kick");
        JMenuItem controlKickWhy = new JMenuItem("Kick (why)");
       
       
        listControl.add(controlOperator);
        listControl.add(controlDeOperator);
        listControl.add(controlKick);
        listControl.add(controlKickWhy);
      
        
        // adds actionListeners.
        PopupListControlActionlistener(controlOperator,	controlDeOperator, controlKick, controlKickWhy);
	}
	
	
	
	/**
	 * ActionListeners for the main JMenuItems in the popupMenu.
	 * @since 2.1
	 * @version 2.3
	 */
	public void PopupListActionListener(JMenuItem listWhoIs, 
			JMenuItem listChat, JMenuItem listSlap){
		 
		 // WhoIs
		 listWhoIs.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.WhoIs(nickInUse, myChannelName);
	    	  }
	      });
		 
		 // Chat
		 listChat.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.createChatWindow(nickInUse);
	    	  }
	      });
		 
		 // Slap
		 listSlap.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.SlapUser(nickInUse, myChannelName);
	    	  }
	      });
	}
	
	
	/**
	 * ActionListeners for the JMenuItems in JMenu: control, in the popupMenu. </br>
	 * Only KickUser is applied yet.
	 * @since 2.1
	 * @version 2.3
	 */
	public void PopupListControlActionlistener(JMenuItem controlOperator, JMenuItem controlDeOperator, JMenuItem controlKick,
			JMenuItem controlKickWhy){
		
		// Kick user
		controlKick.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.KickUser(myChannelName, nickInUse);
	    	  }
	      });
		
		// Kick user and write why
		controlKickWhy.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  String why = JOptionPane.showInputDialog ("Write down why you want to kick this user:");
	    		  CC.KickUserWhy(myChannelName, nickInUse, why);
	    	  }
	      });
		
		//OP user
		controlOperator.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.opUser(myChannelName, nickInUse);
	    	  }
	      });
		
		//DEOP user
		controlDeOperator.addActionListener(new ActionListener() {
	    	  public void actionPerformed (ActionEvent ae){
	    		  CC.deOpUser(myChannelName, nickInUse);
	    	  }
	      });
	}
	

	
}
